import axios from 'axios'
import 'sweetalert2-preset/dist/style.css'
import { confirm, error } from 'sweetalert2-preset'
import { pickDeepBy } from '@/utils'
import store from '@/store'
import { getToken, setToken } from '@/utils/auth'
import loginSilently from '@/views/login/components/loginSilently'
import relativeBaseURLHandler from './relativeBaseURLHandler'

const request = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  withCredentials: true,
  timeout: 10000
})

request.interceptors.request.use(
  (config) => {
    relativeBaseURLHandler(config)

    if (config.data === undefined) {
      config.data = {}
    } else {
      // 过滤参数
      config.data = pickDeepBy(
        config.data,
        (v, k) => ![NaN, null, undefined].includes(v) && !k.startsWith('__')
      )
    }

    const token = getToken()
    if (token) {
      config.headers['Authorization'] = token
    }

    return config
  },
  (e) => {
    // do something with request error
    console.log(e) // for debug
    return Promise.reject(e)
  }
)

// response interceptor
request.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
   */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  async (response) => {
    if (response.config.method === 'head') {
      return response
    }

    const res = response.data

    if (res.type) {
      if (res.type === 'application/vnd.ms-excel' || res.type === 'application/x-msdownload') {
        const url = window.URL.createObjectURL(new Blob([res]))
        const link = document.createElement('a')
        link.href = url
        let fileName = response.headers['content-disposition']?.replace('attachment;filename=', '')
        if (fileName) {
          fileName = decodeURIComponent(fileName)
        } else {
          fileName = new Date() + '.xlsx'
        }
        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()
        return
      }
      return res
    }

    const token = response.headers['right-token']
    token && setToken(token)

    if (res.errorCode === '00000') {
      return res
    } else {
      if (res.errorCode === '00002') {
        store.dispatch('user/logout')
      } else if (res.errorCode === '00003') {
        let isLogin = store.getters.isLogin // 是否是在已登录状态
        if (isLogin) {
          store.dispatch('user/logout', true) // 如果已登录的情况下登录失效，不必跳到登录页

          await confirm({
            title: '由于您长时间未操作，\n为了您的账号安全，请重新登录。',
            icon: 'info',
            showCancelButton: false,
            allowOutsideClick: false,
            allowEscapeKey: false
          })

          await loginSilently() // 当前页面调起登录，重新登录
        } else {
          store.dispatch('user/logout') // 未登录的情况下登录失效，直接跳转到登录界面
        }
      } else {
        res.message && error(res.message)
      }

      return Promise.reject(res)
    }
  },
  (e) => {
    if (e.message?.includes('timeout')) {
      e.message = '网络超时'
    } else if (e.message === 'Network Error') {
      e.message = '网络错误'
    }
    e.message && error(e.message)
    return Promise.reject(e)
  }
)

export default request
